package org.kl.wx.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpMassNews;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
import me.chanjar.weixin.mp.bean.WxMpMassVideo;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.entity.basic.BasicFile;
import org.kl.bf.entity.easyui.EasyuiTreeNode;
import org.kl.bf.service.basic.BasicFileService;
import org.kl.bf.utils.BasicConstants;
import org.kl.bf.web.base.BasicController;
import org.kl.wx.entity.App;
import org.kl.wx.entity.Groups;
import org.kl.wx.entity.Media;
import org.kl.wx.entity.WxUser;
import org.kl.wx.service.AppService;
import org.kl.wx.service.GroupsService;
import org.kl.wx.service.MediaAsynInfoService;
import org.kl.wx.service.MediaService;
import org.kl.wx.service.WxUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.web.MediaTypes;

@Controller
@RequestMapping(value = "/wx/sendMessages")
public class MpSendMessagesController extends BasicController {

	@Autowired
	private AppService appService;
	@Autowired
	private GroupsService groupsService;
	@Autowired
	private WxUserService wxUserService;
	@Autowired
	private BasicFileService basicFileService;
	@Autowired
	private MediaAsynInfoService mediaAsynInfoService;
	@Autowired
	private MediaService mediaService;

	@RequestMapping(method = RequestMethod.GET)
	public String list() {
		return "/wx/mpSendMessages";
	}

	@RequestMapping(value = "sendMessages", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String sendMessages(@RequestParam(value = "appId", defaultValue = "") String appId,
			@RequestParam(value = "usersId", defaultValue = "") String usersId,
			@RequestParam(value = "msgType", defaultValue = "") String msgType, ServletRequest request, HttpSession session)
			throws Exception {
		if (StringUtils.isBlank(appId)) {
			return ajaxMsg("发送失败，发送信息的公共账号不能为空！", false, null);
		}
		if (StringUtils.isBlank(usersId)) {
			return ajaxMsg("发送失败，接受信息的用户不能为空！", false, null);
		}

		App app = appService.getApp(appId);
		WxMpService wxMpService = super.getWxMpServiceByToken(session, app.getAppToken());
		WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage();
		WxMediaUploadResult uploadMediaRes = null;
		InputStream inputStream = null;
		if (StringUtils.isBlank(msgType) || StringUtils.equals(msgType, WxConsts.MASS_MSG_TEXT)) {
			/**
			 * 发送文本群消息
			 */
			String test = request.getParameter("test");
			if (StringUtils.isBlank(test)) {
				return ajaxMsg("发送失败，接受内容不能为空！", false, null);
			}
			massMessage.setMsgType(WxConsts.MASS_MSG_TEXT);
			massMessage.setContent(test);
		} else {
			if (StringUtils.equals(msgType, WxConsts.MASS_MSG_VOICE)) {// 消息类型为声音时的处理方法
				String voiceNameId = request.getParameter("voiceNameId");
				if (StringUtils.isBlank(voiceNameId)) {
					return ajaxMsg("发送失败，语音消息不能为空", false, null);
				}
				BasicFile bFile = basicFileService.getBasicFile(voiceNameId);
				File file = new File(bFile.getFilePath());
				try {
					inputStream = new FileInputStream(file);
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，语音消息文件未找到", false, null);
				}
				try {
					uploadMediaRes = wxMpService.mediaUpload(WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, inputStream);
				} catch (WxErrorException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，语音消息文件传输失败", false, null);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，语音消息文件读取失败", false, null);
				}
				massMessage.setMsgType(WxConsts.MASS_MSG_VOICE);
				massMessage.setMediaId(uploadMediaRes.getMediaId());
				// 图文消息存到本地
				Media media = mediaService.saveMedia(msgType, "", "", file);
				mediaAsynInfoService.saveMediaAsynInfo(app, uploadMediaRes.getMediaId(), media);
			} else if (StringUtils.equals(msgType, WxConsts.MASS_MSG_IMAGE)) {// 消息类型为图片时的处理方法
				String imageNameId = request.getParameter("imageNameId");
				if (StringUtils.isBlank(imageNameId)) {
					return ajaxMsg("发送失败，图片不能为空", false, null);
				}
				BasicFile bFile = basicFileService.getBasicFile(imageNameId);
				File file = new File(bFile.getFilePath());
				try {
					inputStream = new FileInputStream(file);
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，图片未找到", false, null);
				}
				try {
					uploadMediaRes = wxMpService.mediaUpload(WxConsts.MASS_MSG_IMAGE, WxConsts.FILE_JPG, inputStream);
				} catch (WxErrorException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，图片传输失败", false, null);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，图片读取失败", false, null);
				}
				massMessage.setMsgType(WxConsts.MASS_MSG_IMAGE);
				massMessage.setMediaId(uploadMediaRes.getMediaId());
			} else if (StringUtils.equals(msgType, WxConsts.MEDIA_VIDEO)) {// 消息类型为图片时的处理方法
				String videoNameId = request.getParameter("videoNameId");
				if (StringUtils.isBlank(videoNameId)) {
					return ajaxMsg("发送失败，视频不能为空", false, null);
				}
				BasicFile bFile = basicFileService.getBasicFile(videoNameId);
				File file = new File(bFile.getFilePath());

				try {
					inputStream = new FileInputStream(file);

				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，视频未找到", false, null);
				}
				try {
					uploadMediaRes = wxMpService.mediaUpload(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream);

				} catch (WxErrorException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，视频传输失败", false, null);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，视频读取失败", false, null);
				}
				WxMpMassVideo video = new WxMpMassVideo();
				video.setTitle(request.getParameter("videoTitle"));
				video.setDescription(request.getParameter("videoDescription"));
				video.setMediaId(uploadMediaRes.getMediaId());
				WxMpMassUploadResult uploadResult = null;
				try {
					uploadResult = wxMpService.massVideoUpload(video);
				} catch (WxErrorException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return ajaxMsg("发送失败，视频读取失败", false, null);
				}
				massMessage.setMsgType(WxConsts.MEDIA_VIDEO);
				massMessage.setMediaId(uploadResult.getMediaId());
				Media media = mediaService.saveMedia(msgType, request.getParameter("videoTitle"), request.getParameter("videoDescription"),
						file);
				mediaAsynInfoService.saveMediaAsynInfo(app, uploadMediaRes.getMediaId(), media);
			} else {
				Integer newsMsgNumber = Integer.valueOf(request.getParameter("msgNumber"));
				WxMpMassNews news = new WxMpMassNews();
				for (int i = 0; i < newsMsgNumber; i++) {
					String newsImage = request.getParameter("newsImageId" + i);
					if (StringUtils.isBlank(newsImage)) {
						return ajaxMsg("发送失败，图文消息中图片不能为空", false, null);
					}
					BasicFile bFile = basicFileService.getBasicFile(newsImage);
					File file = new File(bFile.getFilePath());
					try {
						inputStream = new FileInputStream(file);
					} catch (FileNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						return ajaxMsg("发送失败，图文消息中图片未找到", false, null);
					}
					try {
						uploadMediaRes = wxMpService.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream);
					} catch (WxErrorException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						return ajaxMsg("发送失败", false, null);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						return ajaxMsg("发送失败", false, null);
					}

					WxMpMassNews.WxMpMassNewsArticle article1 = new WxMpMassNews.WxMpMassNewsArticle();
					article1.setTitle(request.getParameter("newsTitle" + i));
					article1.setAuthor(request.getParameter("newsEditor" + i));
					article1.setContentSourceUrl(request.getParameter("newsURL" + i));
					article1.setShowCoverPic(StringUtils.equals(request.getParameter("showCoverPic" + i), "true") ? true : false);
					String content = request.getParameter("newsContent" + i);
					// 如果正文中包含图片的处理方法
					String projectName = (String) session.getServletContext().getAttribute(BasicConstants.CONFIG_PROJECTNAME);
					while (content.contains("/" + projectName + "/")) {
						String change = content.substring(0, content.indexOf("\"/" + projectName) + 1);
						String str = content.substring(content.indexOf("\"/" + projectName),
								content.indexOf("\" ", content.indexOf("\"/" + projectName)) + 1);
						String imgPath = str.substring(str.indexOf(projectName) + projectName.length(),
								str.indexOf("\"", str.indexOf(projectName)));
						imgPath = session.getServletContext().getRealPath("/") + imgPath;
						File fileTwo = new File(imgPath);
						InputStream inputStreamTwo = null;
						try {
							inputStreamTwo = new FileInputStream(fileTwo);
						} catch (FileNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							return ajaxMsg("发送失败，图片未找到", false, null);
						}
						try {
							uploadMediaRes = wxMpService.mediaUpload(WxConsts.MASS_MSG_IMAGE, WxConsts.FILE_JPG, inputStreamTwo);
						} catch (WxErrorException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							return ajaxMsg("发送失败，图片传输失败", false, null);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							return ajaxMsg("发送失败，图片读取失败", false, null);
						}
						change += getMediaString(wxMpService.getAccessToken(), uploadMediaRes.getMediaId());
						change += content.substring(content.indexOf("\" ", content.indexOf("\"/" + projectName)), content.length());
						content = change;
					}
					article1.setContent(content);
					article1.setThumbMediaId(uploadMediaRes.getMediaId());
					news.addArticle(article1);
				}
				WxMpMassUploadResult massUploadResult = null;
				try {
					massUploadResult = wxMpService.massNewsUpload(news);
				} catch (WxErrorException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				massMessage.setMsgType(WxConsts.MASS_MSG_NEWS);
				massMessage.setMediaId(massUploadResult.getMediaId());
			}
		}
		String[] str = usersId.split(",");
		for (String s : str) {
			massMessage.getToUsers().add(s);
		}
		try {
			WxMpMassSendResult massResult = wxMpService.massOpenIdsMessageSend(massMessage);
			System.out.println(massResult.getMsgId());
		} catch (WxErrorException e) {
			e.printStackTrace();
			return ajaxMsg("发送失败", false, null);
		}
		return ajaxMsg("发送成功", true, null);
	}

	@RequestMapping(value = "tree/{appId}", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String tree(@PathVariable("appId") String appId, ServletRequest request, HttpSession session) {
		if (StringUtils.isBlank(appId)) {
			return null;
		}
		Map<String, Object> searchParams = new HashMap<>();
		searchParams.put("EQ_app.id", appId);
		searchParams.put("NEQ-I_userCount", "0");
		List<Groups> groupsList = groupsService.getGroups(searchParams);
		List<EasyuiTreeNode> nodeList = new ArrayList<>();
		for (Groups g : groupsList) {
			EasyuiTreeNode e = groupToNode(g);
			nodeList.add(e);
		}
		return jsonMapper.toJson(nodeList);
	}

	private EasyuiTreeNode groupToNode(Groups g) {
		EasyuiTreeNode one = new EasyuiTreeNode();
		one.setId(g.getId());
		one.setText(g.getGroupName());
		List<WxUser> userList = wxUserService.getByGroups(g.getId());
		List<EasyuiTreeNode> nList = new ArrayList<>();
		for (WxUser user : userList) {
			EasyuiTreeNode e = userToNode(user);
			nList.add(e);
		}
		one.setChildren(nList);
		return one;
	}

	private EasyuiTreeNode userToNode(WxUser user) {
		EasyuiTreeNode one = new EasyuiTreeNode();
		one.setId(user.getOpenid());
		one.setText(user.getNickname());
		one.setPid(user.getGroups().getId());
		return one;
	}

	private String getMediaString(String accessToken, String mediaId) {
		return BasicConstants.MEDIO_URL + BasicConstants.ACCESS_TOKEN + accessToken + BasicConstants.MEDIA_ID + mediaId;
	}
}